package com.boarsoft.dao.sharding.oceanbase.executor;

import com.alipay.sofa.dbp.RouteCondition;
import com.alipay.sofa.dbp.RouteParameters;
import com.boarsoft.dao.sharding.executor.SqlCallBack;
import com.boarsoft.dao.sharding.executor.SqlRouteExecutor;
import com.boarsoft.dao.sharding.executor.SqlVoidCallBack;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.UndeclaredThrowableException;
/**
 *
 * dbp分片sql执行器
 *
 */
public class DbpSqlRouteExecutor implements SqlRouteExecutor {

    /**
     * 指定分库分表执行sql(带返回值)
     *
     * @param tableIndex 分库分表位
     * @param callBack   回调函数
     * @return 执行结果
     */
    @Override
    public Object executeQuery(String tableIndex, SqlCallBack callBack) {
        try {
            RouteParameters routeParameters = RouteCondition.newRouteParameters();
            routeParameters.setGroupId(tableIndex);
            return callBack.doExecute();
        } catch (Exception ex) {
            throw ex;
        } catch (Throwable t) {
            throw new UndeclaredThrowableException(t);
        } finally {
            RouteCondition.clear();
        }
    }

    /**
     * 指定分库分表执行sql(无返回值)
     *
     * @param tableIndex 分库分表位(默认百表范围是00~99)
     * @param callBack   回调函数
     */
    @Override
    public void execute(String tableIndex, SqlVoidCallBack callBack) {

        try {
            RouteParameters routeParameters = RouteCondition.newRouteParameters();
            routeParameters.setGroupId(tableIndex);
            callBack.doExecute();
        } catch (Exception ex) {
            throw ex;
        } catch (Throwable t) {
            throw new UndeclaredThrowableException(t);
        } finally {
            RouteCondition.clear();
        }
    }

    /**
     * 指定分库分表执行sql(无返回值,独立事务)
     *
     * @param tableIndex 分库分表位(默认百表范围是00~99)
     * @param callBack   回调函数
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void executeNewTransaction(String tableIndex, SqlVoidCallBack callBack) {

        try {
            RouteParameters routeParameters = RouteCondition.newRouteParameters();
            routeParameters.setGroupId(tableIndex);
            callBack.doExecute();
        } catch (Exception ex) {
            throw ex;
        } catch (Throwable t) {
            throw new UndeclaredThrowableException(t);
        } finally {
            RouteCondition.clear();
        }
    }
}